namespace OracleInternal.BinXml
{
	internal class ObxmlNodeState : ObxmlStateObject
	{
		internal NodeTypes NodeType;

		internal ulong NodeDataLen;

		internal string Prefix;

		internal short PrefixId;

		internal ObxmlNodeState m_ParentNode;

		internal ulong NsIndex;

		internal ObxmlToken m_ElementToken;

		private string qualifiedName;

		internal string m_PrefixWhiteSpaces;

		internal int NodeLevel;

		internal bool PendingDataNode;

		internal NodeFlags NodeMask;

		internal int ArrayModeCount;

		internal int ChildNodesCount;

		internal int NodeId;

		internal bool IsOptimizedOpcode;

		internal bool HasPrefix => Prefix != null;

		internal bool IsAttribute => NodeTypes.Attribute == NodeType;

		internal bool IsArrayMode => (NodeMask & NodeFlags.ARRMODE) > NodeFlags.SELFMODE;

		internal bool IsSequentialMode => (NodeMask & NodeFlags.SEQMODE) > NodeFlags.SELFMODE;

		internal void SetArrayMode(bool hasArrayMode)
		{
			if (hasArrayMode)
			{
				NodeMask |= NodeFlags.ARRMODE;
				return;
			}
			ArrayModeCount = 0;
			NodeMask &= ~NodeFlags.ARRMODE;
		}

		public ObxmlNodeState()
		{
			Reset();
		}

		internal void ResetObxmlNodeState(NodeTypes nodeType, ObxmlToken token)
		{
			Reset();
			NodeType = nodeType;
			m_ElementToken = token;
			NodeDataLen = 0uL;
			if (token != null)
			{
				NodeType = GetDefaultNodeTypeForTokenType(token.TokenType);
			}
			m_PrefixWhiteSpaces = string.Empty;
			m_ParentNode = null;
			NodeLevel = 1;
			PendingDataNode = false;
		}

		internal void ResetObxmlNodeState(NodeTypes nodeType, ObxmlToken token, ulong nodeDataLen)
		{
			Reset();
			NodeType = nodeType;
			m_ElementToken = token;
			NodeDataLen = nodeDataLen;
			if (token != null)
			{
				NodeType = GetDefaultNodeTypeForTokenType(token.TokenType);
			}
			m_PrefixWhiteSpaces = string.Empty;
			m_ParentNode = null;
			NodeLevel = 1;
			PendingDataNode = false;
		}

		internal override void ClearStateObject()
		{
			Reset();
		}

		internal void Reset()
		{
			IsOptimizedOpcode = false;
			NodeType = NodeTypes.None;
			m_ElementToken = null;
			NodeDataLen = 0uL;
			Prefix = null;
			PrefixId = 0;
			NsIndex = 0uL;
			NodeMask = NodeFlags.SELFMODE;
			m_ParentNode = null;
			qualifiedName = null;
			ArrayModeCount = 0;
			ChildNodesCount = 0;
			m_PrefixWhiteSpaces = null;
			NodeLevel = 1;
			PendingDataNode = false;
			NodeId = 0;
		}

		internal string ConvertToText(ObxmlDecodeState decodeState)
		{
			string str = "Node_Begin ";
			str += GetQualifiedName(decodeState);
			str += ". ";
			if (m_ElementToken != null && m_ElementToken.IsAttribute)
			{
				str += " Is ATTRIBUTE. ";
			}
			str = str + " NodeDataLen " + NodeDataLen;
			str = str + " Prefix " + Prefix;
			str = str + " PrefixId " + PrefixId;
			str = str + " NsIndex " + NsIndex;
			str = str + " NodeMask " + NodeMask;
			str = str + " ArrayModeCount " + ArrayModeCount;
			str = str + " ChildNodesCount " + ChildNodesCount;
			str = str + " NodeLevel " + NodeLevel;
			return str + " Node_End  ";
		}

		internal static NodeTypes GetDefaultNodeTypeForTokenType(TokenTypes tokenType)
		{
			return tokenType switch
			{
				TokenTypes.NamespaceToken => NodeTypes.Namespace, 
				TokenTypes.AttributeToken => NodeTypes.Attribute, 
				TokenTypes.ElementToken => NodeTypes.Element, 
				TokenTypes.PrefixToken => NodeTypes.None, 
				_ => NodeTypes.None, 
			};
		}

		internal static TokenTypes GetDefaultTokenTypeForNodeType(NodeTypes nodeType)
		{
			return nodeType switch
			{
				NodeTypes.Namespace => TokenTypes.NamespaceToken, 
				NodeTypes.Attribute => TokenTypes.AttributeToken, 
				NodeTypes.Element => TokenTypes.ElementToken, 
				NodeTypes.None => TokenTypes.None, 
				_ => TokenTypes.None, 
			};
		}

		internal AttributeInfo GetAttributeInfo(ObxmlDecodeState decodeState, ulong index)
		{
			return decodeState.AttributeList[(int)index];
		}

		internal void AddAttributeInfo(ObxmlDecodeState decodeState, AttributeInfo attributeInfo)
		{
			decodeState.AttributeList.Add(attributeInfo);
		}

		internal string GetQualifiedName(ObxmlDecodeState decodeState)
		{
			if (!string.IsNullOrEmpty(qualifiedName))
			{
				return qualifiedName;
			}
			string prefix = Prefix;
			if (prefix == null && PrefixId > 0)
			{
				prefix = decodeState.GetPrefix(PrefixId);
			}
			if (m_ElementToken == null)
			{
				return qualifiedName = prefix;
			}
			if (string.IsNullOrEmpty(prefix) || string.IsNullOrEmpty(prefix.Trim()))
			{
				return qualifiedName = m_ElementToken.TokenName;
			}
			return qualifiedName = prefix + ":" + m_ElementToken.TokenName;
		}

		internal string SetPrefix(ObxmlDecodeState decodeState, string px)
		{
			if (px != null)
			{
				Prefix = px;
			}
			else if (m_ElementToken.NamespaceId != 0L)
			{
				Prefix = decodeState.GetNSPrefix(m_ElementToken.NamespaceId);
			}
			else if (!string.IsNullOrEmpty(m_ElementToken.Uri))
			{
				Prefix = decodeState.GetNSPrefix(m_ElementToken.Uri);
			}
			else
			{
				Prefix = null;
			}
			return Prefix;
		}

		internal ObxmlNodeState Clone()
		{
			ObxmlNodeState obxmlNodeState = new ObxmlNodeState();
			obxmlNodeState.NodeType = NodeType;
			obxmlNodeState.m_ElementToken = m_ElementToken;
			obxmlNodeState.NodeDataLen = NodeDataLen;
			obxmlNodeState.Prefix = Prefix;
			obxmlNodeState.PrefixId = PrefixId;
			obxmlNodeState.NsIndex = NsIndex;
			obxmlNodeState.NodeMask = NodeFlags.SELFMODE;
			obxmlNodeState.qualifiedName = qualifiedName;
			obxmlNodeState.ArrayModeCount = ArrayModeCount;
			if (obxmlNodeState.NodeType == NodeTypes.None && obxmlNodeState.m_ElementToken != null)
			{
				NodeType = GetDefaultNodeTypeForTokenType(m_ElementToken.TokenType);
			}
			return obxmlNodeState;
		}
	}
}
